package com.xyy.saas.payment.adpater;

import com.alibaba.fastjson.JSONObject;
import com.xyy.saas.payment.adpater.config.BankConfigManager;
import com.xyy.saas.payment.adpater.config.ChannelConfigManager;
import com.xyy.saas.payment.adpater.fumin.pojo.domain.SeparateAccountDO;
import com.xyy.saas.payment.adpater.impl.*;
import com.xyy.saas.payment.cashier.core.vo.ChannelLoginVO;
import com.xyy.saas.payment.channel.login.core.bo.ChannelLoginResultBO;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.config.*;
import com.xyy.saas.payment.cores.bo.*;
import com.xyy.saas.payment.cores.enums.*;
import com.xyy.saas.payment.cores.param.TransactionParam;
import com.xyy.saas.payment.cores.vo.QueryAccountBalanceDO;
import com.xyy.saas.payment.cores.vo.QueryFuminRecordBo;
import com.xyy.saas.payment.cores.vo.ResultVO;
import com.xyy.saas.payment.dao.model.PrePayOrder;
import com.xyy.saas.payment.dao.model.RefundOrder;
import com.xyy.saas.payment.entrust.core.dto.EntrustPayDto;
import com.xyy.saas.payment.entrust.core.dto.EntrustPayInfoDto;
import com.xyy.saas.payment.merchant.core.dto.*;
import com.xyy.saas.payment.merchant.core.service.AccountService;
import com.xyy.saas.payment.merchant.core.vo.PaymentAuthQueryVo;
import com.xyy.saas.payment.merchant.core.vo.PaymentAuthVo;
import com.xyy.saas.payment.merchant.core.vo.UserDto;
import com.xyy.saas.payment.payment.core.bo.RefundBO;
import com.xyy.saas.payment.payment.core.bo.WithdrawalBO;
import com.xyy.saas.payment.payment.core.dto.*;
import com.xyy.saas.payment.payment.core.service.ChannelSwitchService;
import com.xyy.saas.payment.payment.core.service.RiskControlService;
import com.xyy.saas.payment.util.ApolloUtil;
import com.xyy.saas.payment.util.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class RouteManager implements InitializingBean {
    @Value("${fmPopSwitch:true}")
    private Boolean fmPopSwitch;
    @Value("${jd.alipay.switch:true}")
    private Boolean jdAlipaySwitch;
    @Autowired
    private WxAdapter wxAdapter;
    @Autowired
    private AliAdapter aliAdapter;
    @Autowired
    private PingxxAdapter pingxxAdapter;
    @Autowired
    private ChinaBankAdapter chinaBankAdapter;
    @Autowired
    private FuminAdapter fuminAdapter;
    @Resource
    private FuminAdapter2 fuminAdapter2;
    @Autowired
    private BankConfigManager bankConfigManager;
    @Autowired
    private ChannelConfigManager channelConfigManager;
    @Autowired
    private WxCommonAdpter wxCommonAdpter;
    @Autowired
    private AliCommonAdapter aliCommonAdapter;
    @Autowired
    private UnionPayAdapter unionPayAdapter;
    @Autowired
    private RiskControlService riskControlService;
    @Resource
    private ChannelSwitchService channelSwitchService;
    @Resource
    private AccountService accountService;
    @Resource
    private YopAdapter yopAdapter;
    @Resource
    private PinganAdapter pinganAdapter;
    @Resource
    private JDAdapter jdAdapter;
    @Resource
    private JdCreditAdapter jdCreditAdapter;
    @Resource
    private JDAggrateAdapter jdAggregateAdapter;
    @Resource
    private AbchinaLoanAdapter abchinaLoanAdapter;
    @Resource
    private XydLoanAdapter xydLoanAdapter;


    private Map<String, PaymentAdapter> adapters = new HashMap<>();

    @Override
    public void afterPropertiesSet() {
        adapters.put(Constants.CHANNEL_WX_NAME, wxAdapter);
        adapters.put(Constants.CHANNEL_ALI_NAME, aliAdapter);
        adapters.put(Constants.CHANNEL_AGGREGATE_NAME, pingxxAdapter);
        adapters.put(Constants.CHANNEL_CHINA_BANK_NAME, chinaBankAdapter);
        adapters.put(Constants.CHANNEL_FUMIN_BANK_NAME, fuminAdapter);
        adapters.put(Constants.CHANNEL_FUMIN_BANK_NAME_V2, fuminAdapter2);
        adapters.put(Constants.CHANNEL_DIRECT_NAME_ALIPAY, aliCommonAdapter);
        adapters.put(Constants.CHANNEL_DIRECT_NAME_WX, wxCommonAdpter);
        adapters.put(Constants.CHANNEL_UNIONPAY_NAME, unionPayAdapter);
        adapters.put(Constants.CHANNEL_YOP_NAME, yopAdapter);
        adapters.put(Constants.CHANNEL_PINGAN_NAME, pinganAdapter);
        adapters.put(Constants.CHANNEL_JD_CARD_NAME, jdAdapter);
        adapters.put(Constants.CHANNEL_JDAGGREGATE_NAME, jdAggregateAdapter);
        adapters.put(Constants.CHANNEL_JD_CREDIT, jdCreditAdapter);
        adapters.put(Constants.CHANNEL_ABCHINA_LOAN, abchinaLoanAdapter);
        adapters.put(Constants.CHANNEL_XYD_LOAN, xydLoanAdapter);
    }

    /**
     * 获取路由
     */
    private String getRoute(String payChannel, String type, String accountId) {
        if (Objects.equals(payChannel, Constants.CHANNEL_XYD_LOAN)) {
            return payChannel;
        }
        if (Objects.equals(payChannel, Constants.CHANNEL_ABCHINA_LOAN)) {
            return payChannel;
        }
        if (payChannel.equals(Constants.CHANNEL_JD_CREDIT)) {
            return payChannel;
        }
        if(!StringUtils.isBlank(payChannel) && payChannel.contains(Constants.CHANNEL_UNIONPAY_NAME)) {
            return channelConfigManager.getAdapterName(payChannel);
        }
        if (!StringUtils.isBlank(payChannel) && Constants.thirdChannelSubmitPingan(payChannel)) {
            return Constants.transThirdCahnnelSubmitPingan(payChannel);
        }

        if(StringUtils.isNotBlank(type)) {
            String route = bankConfigManager.checkRoute(type, accountId);
            if (Constants.CHANNEL_FUMIN_BANK_NAME.equals(route) && BusinessOrderTypeEnum.EC_POP.getType().equals(type)) {
                return channelConfigManager.getAdapterName(payChannel);
            }
            if(route != null) {
                return route;
            }
        }

        if(payChannel.contains(Constants.CHANNEL_CHINA_BANK_NAME)) {
            return Constants.CHANNEL_CHINA_BANK_NAME;
        }

        if(payChannel.contains(Constants.CHANNEL_FUMIN_BANK_NAME)) {
            return Constants.CHANNEL_FUMIN_BANK_NAME;
        }

        if(payChannel.contains(Constants.CHANNEL_YOP_NAME)) {
            return Constants.CHANNEL_YOP_NAME;
        }

        if(payChannel.contains(Constants.CHANNEL_PINGAN_NAME)) {
            return Constants.CHANNEL_PINGAN_NAME;
        }

        if(payChannel.contains(Constants.CHANNEL_DIRECT_NAME)) {
            return channelConfigManager.getAdapterName(payChannel);
        }

        //再检查是不是ping++
        if(payChannel.contains(Constants.CHANNEL_AGGREGATE_NAME)) {
            return channelConfigManager.checkRoute(type, payChannel);
        }
        else {
            return payChannel;
        }
    }

    /**
     * 获取路由
     */
    public PaymentAdapter getAdapter(String key, String type, String accountId) {
       return adapters.get(getRoute(key, type, accountId));
    }

    /**
     * 第三方登录 获取 userId 或者 openId
     */
    public ChannelLoginResultBO login(ChannelLoginVO channelLoginVO, String key) throws PaymentException {
        return getAdapter(key, StringUtils.EMPTY, StringUtils.EMPTY).login(channelLoginVO);
    }

    /**
     * 预支付
     */
    public PrepayBo prepay(PrepayDto prepayDto, String key) throws PaymentException {
       return getAdapter(key, prepayDto.getBusinessOrderType(), prepayDto.getUserId()).prepay(prepayDto);
    }

    public RefundBO notifyRefund(RefundDto refundDto) throws PaymentException {
        return adapters.get(getRoute(refundDto.getChannel(), Boolean.TRUE.equals(refundDto.getBusinessIdTypeRoute()) ?
                refundDto.getBusinessOrderType() : StringUtils.EMPTY, refundDto.getReceiverId())).notifyRefund(refundDto);
    }

    /**
     * 退款
     */
    public RefundBO refund(RefundDto refundDto) throws PaymentException {
        // 若渠道为三方渠道 且 BusinessIdTypeRoute为true，否则转为走平安渠道退款(充值撤销)
        if(refundDto.getBusinessIdTypeRoute() && Constants.thirdChannelSubmitPingan(refundDto.getChannel())) {
            return adapters.get(Constants.CHANNEL_PINGAN_NAME).refund(refundDto);
        }
        return adapters.get(getRoute(refundDto.getChannel(), Boolean.TRUE.equals(refundDto.getBusinessIdTypeRoute()) ?
                refundDto.getBusinessOrderType() : StringUtils.EMPTY, refundDto.getReceiverId())).refund(refundDto);
    }

    /**
     * 检查交易状态是否完成
     */
    public QueryResultBo queryTransactionStatus(QueryTransactionStatusDto queryTransactionStatusDto, String payChannel) throws PaymentException {
        return adapters.get(getRoute(payChannel, queryTransactionStatusDto.getBusinessOrderType(), queryTransactionStatusDto.getAccountId())).queryTransactionStatus(queryTransactionStatusDto);
    }

    /**
     * 提现
     */
    public WithdrawalBO withdraw(WithdrawalDto withdrawalDto, String key) throws PaymentException {
        return getAdapter(key, withdrawalDto.getBusinessIdType(), withdrawalDto.getUserId()).withdraw(withdrawalDto);
    }

    /**
     * 提现鉴权
     */
    public WithdrawalBO withdrawAuth(WithdrawAuthDto withdrawAuthDto) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, withdrawAuthDto.getBusinessIdType(), withdrawAuthDto.getAccountId()).withdrawAuth(withdrawAuthDto);
    }

    /**
     * 上传商户证件
     */
    public UserPicBo uploadPic(UserDto userDto, String key) throws PaymentException {
        return getAdapter(key, userDto.getBusinessIdType(), userDto.getUserId()).uploadPic(userDto);
    }

    /**
     * 查询账户余额
     */
    public UserBo queryAccount(QueryAccountDto queryAccountDto) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, queryAccountDto.getBusinessIdType(), queryAccountDto.getUserId()).queryAccount(queryAccountDto);
    }

    /**
     * 查询支付单状态
     */
    public QueryResultBo queryPayStatus(String tradeNo, String key, PrePayOrder prePayOrder) throws PaymentException {
        return queryPayStatus(tradeNo, key, prePayOrder, StringUtils.EMPTY);
    }

    /**
     * 查询支付单状态
     */
    public QueryResultBo queryPayStatus(String tradeNo, String key, PrePayOrder prePayOrder, String payMode) throws PaymentException {
        return getAdapter(key, prePayOrder.getBusinessOrderType(), prePayOrder.getReceiverId()).queryPayStatus(tradeNo, prePayOrder, payMode);
    }

    /**
     * 查询交易状态
     */
    public TransactionResultBO queryTransaction(TransactionParam param) throws PaymentException {
        return getAdapter(param.getChannel(), param.getBusinessOrderType(), param.getAccountId()).queryTransaction(param);
    }

    /**
     * 查询退款单状态
     */
    public QueryResultBo queryRefundStatus(RefundOrder refundOrder, String businessOrderType, String key) throws PaymentException {
        return getAdapter(key, businessOrderType, refundOrder.getUserId()).queryRefundStatus(refundOrder);
    }

    /**
     * 预支付
     */
    public AppPayBo appPay(AppPayDto appPayDto, String key) throws PaymentException {
        return getAdapter(key, StringUtils.EMPTY, appPayDto.getReceiverId()).appPay(appPayDto);
    }

    /**
     * 预支付
     */
    public MiniPayBo miniPay(MiniPayDto miniPayDto, String key) throws PaymentException {
        return getAdapter(key, StringUtils.EMPTY, miniPayDto.getReceiverId()).miniPay(miniPayDto);
    }

    /**
     * 支付
     */
    public PayBo pay(PayDto payDto, String key) throws PaymentException {
        return getAdapter(key, payDto.getBusinessOrderType(), payDto.getReceiverId()).pay(payDto);
    }

    /**
     * 创建企业账户
     */
    public SubAppBo createMerchant(UserDto userDto, String key) throws PaymentException {
        return getAdapter(key, userDto.getBusinessIdType(), userDto.getUserId()).createMerchant(userDto);
    }
    /**
     * 创建个人账户
     */
    public SubAppBo createPersonal(UserDto userDto, String key) throws PaymentException {
        return getAdapter(key, userDto.getBusinessIdType(), userDto.getUserId()).createPersonal(userDto);
    }

    /**
     * 订单关闭
     */
    public OrderClosedBo orderClosed(OrderClosedDto orderClosedDto, String key) throws PaymentException {
        return getAdapter(key, orderClosedDto.getBusinessOrderType(), StringUtils.EMPTY).orderClosed(orderClosedDto);
    }

    /**
     * 发送验证码
     */
    public void sendActiveCodeByPhoneNum(ActiveCodeDto activeCodeDto) throws PaymentException {
        getAdapter(StringUtils.EMPTY, activeCodeDto.getBusinessIdType(), activeCodeDto.getAccountId()).sendActiveCodeByPhoneNum(activeCodeDto);
    }


    /**
     * 可降级支付
     */
    public ResultVO<PayBo> channelDegradedPay(PayDto payDto,PrePayOrder prePayOrder) throws PaymentException {
        ResultVO resultVO = new ResultVO<>();
        String route = getRoute(payDto.getChannel(), payDto.getBusinessOrderType(), prePayOrder.getReceiverId());
        boolean isPayerExistValidWhitelist = riskControlService.isRiskControl(prePayOrder.getBusinessType(), prePayOrder.getPayer(), RiskControlBusinessTypeEnum.PAYER.getType());
        boolean isPayeeExistValidWhitelist = riskControlService.isRiskControl(prePayOrder.getBusinessType(), prePayOrder.getReceiverId(),
                RiskControlBusinessTypeEnum.MERCHANT.getType(), payDto.getChannel(), payDto.getPayMode(), payDto.getPayScene());
        log.info("RiskControlService#isRiskControl{} isPayerWhitelist:{}, isPayeeWhitelist:{} {} {}",prePayOrder.getPayNo(), isPayerExistValidWhitelist, isPayeeExistValidWhitelist,route,payDto.getChannel());

        // 京东绑卡支付
        if (Constants.CHANNEL_JD_CARD_NAME.equals(route)) {
            PayBo payBo = jdAdapter.pay(payDto);
            resultVO = (StringUtils.isBlank(payBo.getPayNO()) ? ResultVO.createError(ResultCodeEnum.ORDER_TIME_EXPIRE) : ResultVO.createSuccess(payBo));
        }
        // 小雨点
        else if (Constants.CHANNEL_XYD_LOAN.equals(route)) {
            PayBo payBo = xydLoanAdapter.pay(payDto);
            resultVO = (StringUtils.isBlank(payBo.getPayNO()) ? ResultVO.createError(ResultCodeEnum.ORDER_TIME_EXPIRE) : ResultVO.createSuccess(payBo));
        }
        // 农行链e贷
        else if (Constants.CHANNEL_ABCHINA_LOAN.equals(route)) {
            PayBo payBo = abchinaLoanAdapter.pay(payDto);
            resultVO = (StringUtils.isBlank(payBo.getPayNO()) ? ResultVO.createError(ResultCodeEnum.ORDER_TIME_EXPIRE) : ResultVO.createSuccess(payBo));
        }
        else if (Constants.CHANNEL_JD_CREDIT.equals(route)) {
            PayBo payBo = jdCreditAdapter.pay(payDto);
            resultVO = (StringUtils.isBlank(payBo.getPayNO()) ? ResultVO.createError(ResultCodeEnum.ORDER_TIME_EXPIRE) : ResultVO.createSuccess(payBo));
        }
        else if(BusinessOrderTypeEnum.EC_POP.getType().equals(prePayOrder.getBusinessOrderType())) {

            boolean openAccountComplete = accountService.checkOpenAccountComplete(prePayOrder.getReceiverId());
            boolean pubNeedDirectChannel = Boolean.parseBoolean(ApolloUtil.getProperty(Constants.FBANK_PLATFORM_PUB_DIRECT_PAY_SWITCH, Boolean.TRUE.toString())) &&
                    PayModeEnum.PUB.getMode().equals(payDto.getPayMode()) &&
                    !openAccountComplete;
            log.info("RiskControlService#isRiskControl {}, {}, {},{},{}",prePayOrder.getPayNo(), route,prePayOrder.getPayer(),payDto.getChannel(),openAccountComplete);

            Object withdrawCardTypeObj = JSONUtils.getValueFromJson(prePayOrder.getExtra(), "settleWithdrawType");
            String withdrawCardType = withdrawCardTypeObj == null ? "": (String) withdrawCardTypeObj;
            log.info("channelDegradedPay payno:{} withdrawCardType:{}",prePayOrder.getPayNo(),withdrawCardType);
            // 白名单
            if(isPayerExistValidWhitelist || isPayeeExistValidWhitelist) {
                if (fmPopSwitch && payDto.getChannel().contains(ChannelEnum.WX.getCode())) {
                    log.info("isRiskControl fm 京东聚合支付01 {}",prePayOrder.getPayNo());
                    resultVO = new DegradedPay4JdAggrateHystrixCommand(payDto, jdAggregateAdapter, this).execute();
                } else if (jdAlipaySwitch && payDto.getChannel().equals(ChannelEnum.JDAGGREGATE_ALIPAY.getCode())) {
                    log.info("京东支付宝 {}",prePayOrder.getPayNo());
                    resultVO = new DegradedPay4JdAggrateHystrixCommand(payDto, jdAggregateAdapter, this).execute();
                } else if (payDto.getChannel().contains(ChannelEnum.ALIPAY.getCode())) {
//                    resultVO = fallBackDegradedPay(payDto);
                    PayBo payBo = aliCommonAdapter.pay(payDto);
                    resultVO.setResult(payBo);
                }

            }
            //提现到个人卡走直连
            else if (payDto.getChannel().contains(ChannelEnum.ALIPAY.getCode()) && withdrawCardType!=null && Constants.PERSONAL_WITHDRAW_CARD.equals(withdrawCardType)) {
                PayBo payBo = aliCommonAdapter.pay(payDto);
                resultVO.setResult(payBo);
            }
            // 平安
            else if(Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_PINGAN_PAY_SWITCH_EC_POP)) &&
                    Constants.CHANNEL_PINGAN_NAME.equals(route))
            {
                resultVO = new DegradedPay4PinganHystrixCommand(payDto, pinganAdapter, this).execute();
            }
            // POP大商户切平安
            else if(Boolean.parseBoolean(ApolloUtil.getProperty(Constants.EC_POP_BIG_SHOP_TO_PINGAN_SWITCH, Boolean.FALSE.toString())) &&
                    Objects.equals(ApolloUtil.getProperty(Constants.POP_DIRECT_PAY_YBM_TECH_USER_ID), payDto.getReceiverId()) &&
                    PayModeEnum.MINI.getMode().equals(payDto.getPayMode()))
            {
                resultVO = new DegradedPay4PinganHystrixCommand(payDto, pinganAdapter, this).execute();
            }
            // 富民
            else if(Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_FM_BANK_PAY_SWITCH_EC_POP)) &&
                // 业务切富民
                !Objects.equals(ApolloUtil.getProperty(Constants.POP_DIRECT_PAY_YBM_TECH_USER_ID), payDto.getReceiverId()) &&
                // 支付平台切富民
                channelSwitchService.exits(prePayOrder.getReceiverId()) &&
                // 富民渠道
                Constants.CHANNEL_FUMIN_BANK_NAME.equals(route) &&
                // 平台轮训户特殊判断，进件未完成+微信公众号
                !pubNeedDirectChannel)
            {
                resultVO = new DegradedPay4FMBankHystrixCommand(payDto, fuminAdapter, this).execute();
            }
            // 京东聚合支付
            else if (Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_JDAGGREGATE_PAY_SWITCH, Boolean.FALSE.toString())) &&
                    route.startsWith(Constants.CHANNEL_JDAGGREGATE_NAME))
            {
                resultVO = new DegradedPay4JdAggrateHystrixCommand(payDto, jdAggregateAdapter, this).execute();
            }
            else {
                resultVO = fallBackDegradedPay(payDto);
            }
        }
        // 平安
        else if(Constants.CHANNEL_PINGAN_NAME.equals(route) && !ChannelEnum.PINGAN_CREDIT.getCode().equals(payDto.getChannel())) {
            if(Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_PINGAN_PAY_SWITCH_EC_SELF, Boolean.TRUE.toString())) &&
                // 买家不在直连白名单
                !isPayerExistValidWhitelist &&
                // 卖家不在直连白名单
                !isPayeeExistValidWhitelist)
            {
                resultVO = new DegradedPay4PinganHystrixCommand(payDto, pinganAdapter, this).execute();
            }
            else {
                resultVO = fallBackDegradedPay(payDto);
            }
        }
        // 富民
        else if(Constants.CHANNEL_FUMIN_BANK_NAME.equals(route) || Constants.CHANNEL_FUMIN_BANK_NAME_V2.equals(route)) {
            if(Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_FM_BANK_PAY_SWITCH)) &&
               // 买家不在直连白名单
               !isPayerExistValidWhitelist &&
               // 卖家不在直连白名单
               !isPayeeExistValidWhitelist)
            {
                resultVO = new DegradedPay4FMBankHystrixCommand(payDto, fuminAdapter, this).execute();
            }
            else {
                resultVO = fallBackDegradedPay(payDto);
            }
        }
        // 易宝
        else if(Constants.CHANNEL_YOP_NAME.equals(route)) {
            if(Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_YOP_PAY_SWITCH)) &&
                    // 卖家不在直连白名单
                    !isPayeeExistValidWhitelist)
            {
                resultVO = new DegradedPay4YopHystrixCommand(payDto, yopAdapter, this).execute();
            }
            else {
                resultVO = fallBackDegradedPay(payDto);
            }
        }
        // 中行
        else if(Constants.CHANNEL_CHINA_BANK_NAME.equals(route)) {
            // 如果开关开启
            if(Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_CHINA_BANK_PAY_SWITCH)) && !isPayerExistValidWhitelist) {
                resultVO = new DegradedPay4ChinaBankHystrixCommand(payDto, chinaBankAdapter, this).execute();
            }
            //如果开关关闭
            else {
                resultVO = fallBackDegradedPay(payDto);
            }
        }
        // 京东聚合支付
        else if (route.startsWith(Constants.CHANNEL_JDAGGREGATE_NAME)) {
            // 如果开关开启
            if (Boolean.parseBoolean(ApolloUtil.getProperty(Constants.CHANNEL_JDAGGREGATE_PAY_SWITCH, Boolean.FALSE.toString())) && !isPayeeExistValidWhitelist) {
                resultVO = new DegradedPay4JdAggrateHystrixCommand(payDto, jdAggregateAdapter, this).execute();
            }
            //如果开关关闭
            else {
                resultVO = fallBackDegradedPay(payDto);
            }
        }
        else {
            resultVO.setResult(pay(payDto, payDto.getChannel()));
        }

        return resultVO;
    }

    /**
     * 降级支付
     */
    public ResultVO<PayBo> fallBackDegradedPay(PayDto payDto) throws PaymentException {
        ResultVO<PayBo> resultVO = new ResultVO<>();
        PayBo payBo = null;
        String channel = payDto.getChannel();
        if (channel.contains(ChannelEnum.WX.getCode())) {
            payBo = wxCommonAdpter.pay(payDto);
        }

        if (channel.contains(ChannelEnum.ALIPAY.getCode())) {
            payBo = aliCommonAdapter.pay(payDto);
        }

        resultVO.setResult(payBo);
        return resultVO;
    }
    /**
     * 降级支付
     */
    public ResultVO<PayBo> fallBackDegradedPayForJD(PayDto payDto) throws PaymentException {

        log.info("fallBackDegradedPayForJD:{}", JSONObject.toJSONString(payDto));
        ResultVO<PayBo> resultVO = new ResultVO<>();
        PayBo payBo = null;
        String channel = payDto.getChannel();
        String businessOrderType = payDto.getBusinessOrderType();
        if(StringUtils.isNotBlank(businessOrderType)
                && businessOrderType.contains(Constants.EC_BUSINESS_ORDER_TYPE_PREFIX)
                && channel.contains(ChannelEnum.WX.getCode())) {
            payBo = pinganAdapter.pay(payDto);

        } else if (channel.contains(ChannelEnum.WX.getCode())) {
            payBo = wxCommonAdpter.pay(payDto);
        }

        if(channel.contains(ChannelEnum.ALIPAY.getCode())) {
            payBo = aliCommonAdapter.pay(payDto);
        }

        resultVO.setResult(payBo);
        return resultVO;
    }

    /**
     * 进件
     */
    public CreateAllPayBo createAllPay(CreateAllPayDto createAllPayDto) throws PaymentException {
        return getAdapter(createAllPayDto.getAccountChannel(), createAllPayDto.getBusinessIdType(), createAllPayDto.getUserId()).createAllPay(createAllPayDto);
    }

    /**
     * 开支付功能状态查询
     */
    public Map<String, Boolean> queryOpenPay(String accountId, String businessIdType) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, businessIdType, accountId).queryOpenPay(accountId, businessIdType);
    }

    /**
     * 绑定个人银行卡
     */
    public void personalCardBind(PersonalCardBindDto personalCardBindDto) throws PaymentException {
        getAdapter(StringUtils.EMPTY, personalCardBindDto.getBusinessIdType(), personalCardBindDto.getUserId()).personalCardBind(personalCardBindDto);
    }

    /**
     * 绑定企业银行卡
     */
    public String merchantCardBind(MerchantCardBindDto merchantCardBindDto) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, merchantCardBindDto.getBusinessIdType(), merchantCardBindDto.getUserId()).merchantCardBind(merchantCardBindDto);
    }

    /**
     * 解绑银行卡
     */
    public void unBindCard(UnBindCardDto unBindCardDto) throws PaymentException {
        getAdapter(StringUtils.EMPTY, unBindCardDto.getBusinessIdType(), unBindCardDto.getUserId()).unBindCard(unBindCardDto);
    }

    /**
     * 签约
     */
    public EntrustBO entrustSign(EntrustPayInfoDto entrustPayInfoDto) throws PaymentException {
        return getAdapter(entrustPayInfoDto.getChannel(), entrustPayInfoDto.getBusinessType(), StringUtils.EMPTY).entrustSign(entrustPayInfoDto);
    }

    /**
     * 签约后的代扣支付
     */
    public EntrustPayBO entrustPay(EntrustPayDto entrustPayDto) throws PaymentException {
        return getAdapter(entrustPayDto.getChannel(), entrustPayDto.getBusinessType(), StringUtils.EMPTY).entrustPay(entrustPayDto);
    }

    /**
     * 资金冻结
     */
    public FrozenBo frozenBalance(FrozenDto frozenDto) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, frozenDto.getBusinessOrderType(), frozenDto.getAccountId()).frozenBalance(frozenDto);
    }

    /**
     * 资金解冻
     */
    public UnfrozenBo unfrozenBalance(UnfrozenDto unfrozenDto) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, unfrozenDto.getBusinessOrderType(), unfrozenDto.getAccountId()).unfrozenBalance(unfrozenDto);
    }

    /**
     * 账户转账
     */
    public SeparateAccountsBo separateAccountBetweenUser(SeparateAccountDO separateAccountDO) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, separateAccountDO.getBusinessOrderType(), separateAccountDO.getCustNoIn()).separateAccountBetweenUser(separateAccountDO);
    }

    /**
     * 查询账户流水
     */
    public QueryFuminRecordBo queryBalanceRecord(QueryAccountBalanceDO queryAccountBalanceDO) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, queryAccountBalanceDO.getBusinessOrderType(), queryAccountBalanceDO.getUserId()).queryBalanceRecord(queryAccountBalanceDO);
    }

    /**
     * 修改企业信息
     */
    public AccountModifyBo modifyMerchant(MerchantAccountModifyDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType().getType(), param.getAccountId()).modifyMerchant(param);
    }

    /**
     * 修改个人信息
     */
    public AccountModifyBo modifyPersonal(PersonalAccountModifyDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType().getType(), param.getAccountId()).modifyPersonal(param);
    }

    /**
     * 查询打款认证结果
     */
    public PaymentAuthQueryVo paymentAuthQuery(PaymentAuthQueryDto paymentAuthQueryDto) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, paymentAuthQueryDto.getBusinessIdType(), paymentAuthQueryDto.getAccountId()).paymentAuthQuery(paymentAuthQueryDto);
    }

    /**
     * 打款认证
     */
    public PaymentAuthVo paymentAuth(PaymentAuthDto paymentAuthDto) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, paymentAuthDto.getBusinessIdType(), paymentAuthDto.getAccountId()).paymentAuth(paymentAuthDto);
    }

    /**
     * 冻结充值
     */
    public RechargePayVo rechargePay(RechargePayDto param) throws PaymentException {
        if (RechargePayDto.PAY_CHANNEL_JD.equals(param.getChannel())) {
            return adapters.get(Constants.CHANNEL_PINGAN_NAME).rechargePay(param);
        }
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).rechargePay(param);
    }

    /**
     * 非冻结充值
     */
    public RechargePayVo commonRechargePay(CommonRechargePayDto param) throws PaymentException {
        if (RechargePayDto.PAY_CHANNEL_JD.equals(param.getChannel())) {
            return adapters.get(Constants.CHANNEL_PINGAN_NAME).commonRechargePay(param);
        }
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).commonRechargePay(param);
    }

    /**
     * 非冻结充值撤销
     */
    public RechargeRefundVo commonRechargeRefund(CommonRechargeRefundDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).commonRechargeRefund(param);
    }

    /**
     * 会员间交易
     */
    public AccountTransferVo accountTransfer(AccountTransferDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getInAccountId()).accountTransfer(param);
    }

    /**
     * 会员间交易退款
     */
    public AccountTransferRefundVo accountTransferRefund(AccountTransferRefundDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getOrigInAccountId()).accountTransferRefund(param);
    }

    /**
     * 分账
     */
    public SettleOrderVo settleOrder(SettleOrderDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).settleOrder(param);
    }

    /**
     * 分账撤销
     */
    public SettleCancelVo settleCancel(SettleCancelDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).settleCancel(param);
    }

    /**
     * 查询订单冻结余额
     */
    public OrderAmountInfoVo queryOrderAmountInfo(OrderAmountInfoDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).queryOrderAmountInfo(param);
    }

    /**
     * 查询银行清算结果
     */
    public QueryChannelClearVo queryChannelClear(QueryChannelClearDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).queryChannelClear(param);
    }

    /**
     * 登记挂账
     */
    public RegisterOrderVo registerOrder(RegisterOrderDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).registerOrder(param);
    }

    /**
     * 查询平台见证交易状态
     */
    public QueryTradeStatusVo queryTradeStatus(QueryTradeStatusDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).queryTradeStatus(param);
    }

    /**
     * 提现退汇查询
     */
    public WithdrawRefundVo withdrawRefund(WithdrawRefundDto param) throws PaymentException {
        return pinganAdapter.withdrawRefund(param);
    }

    /**
     * 查询对账文件信息
     */
    public QueryReconciliationFileVo downReconciliationFile(QueryReconciliationFileDto param) throws PaymentException {
        return pinganAdapter.downReconciliationFile(param);
    }

    /**
     * 补单
     */
    public OrderSupplyVo orderSupply(OrderSupplyDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).orderSupply(param);
    }

    /**
     * 查询方法账户ID
     */
    public QueryThirdUserIdVo queryThirdUserId(QueryThirdUserIdDto param) throws PaymentException {
        return getAdapter(StringUtils.EMPTY, param.getBusinessIdType(), param.getAccountId()).queryThirdUserId(param);
    }

    /**
     * 查询交易凭证信息
     */
    public TradeCertificateVo queryTradeCertificate(QueryTradeCertificateDto param) throws PaymentException {
        return getAdapter(param.getPayChannel(), null, null).queryTradeCertificate(param);
    }
}